package com.rerun.common.rabbitmq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * The type Rabbit mq producer.
 *
 * @author dax.
 * @version v1.0
 * @since 2017 /11/17 13:09
 */
@Component
public class RabbitMqProducer {

    private static final Logger log = LoggerFactory.getLogger(RabbitMqProducer.class);


    private boolean durable;
    private boolean autoDelete;
    private String queueName;
    private String exchangeName;
    private String routingKey;
    private ExchangeTypeEnum exchangeTypeEnum;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private RabbitAdmin rabbitAdmin;

    /**
     * Instantiates a new Rabbit mq producer.
     */
    public RabbitMqProducer() {
    }

    /**
     * Instantiates a new Rabbit mq producer.
     *
     * @param durable          the durable
     * @param autoDelete       the auto delete
     * @param queueName        the queue name
     * @param exchangeName     the exchangeName name
     * @param routingKey       the routing key
     * @param exchangeTypeEnum the exchangeName type enum
     */
    public RabbitMqProducer(boolean durable, boolean autoDelete, String queueName, String exchangeName, String routingKey, ExchangeTypeEnum exchangeTypeEnum) {
        this.durable = durable;
        this.autoDelete = autoDelete;
        this.queueName = queueName;
        this.exchangeName = exchangeName;
        this.routingKey = routingKey;
        this.exchangeTypeEnum = exchangeTypeEnum;
        admin();
    }

    public void admin() {
        Queue queue = new Queue(this.queueName);
        rabbitAdmin.declareQueue(queue);

        Exchange exchange = newExchange();
        rabbitAdmin.declareExchange(exchange);

        Binding binding = BindingBuilder.bind(queue).to(exchange).with(routingKey).and(null);
        rabbitAdmin.declareBinding(binding);
    }

    /**
     * Send.
     *
     * @param message the message
     */
    public void send(Object message) {

        this.rabbitTemplate.convertAndSend(message);
    }

    /**
     * Send.
     *
     * @param exchange   the exchangeName
     * @param routingKey the routing key
     * @param message    the message
     */
    public void send(String exchange, String routingKey, Object message) {
               log.info(">>>>>>>>>>>>>>>>>>>>>"+message.toString());
        this.rabbitTemplate.convertAndSend(exchange, routingKey, message);
    }


    private Exchange newExchange() {
        if ("TOPIC".equals(this.exchangeTypeEnum.getKey())) {
            return new TopicExchange(exchangeName, durable, autoDelete, null);
        }

        if ("FANOUT".equals(this.exchangeTypeEnum.getKey())) {
            return new FanoutExchange(exchangeName, durable, autoDelete, null);
        }
        if ("HEADER".equals(this.exchangeTypeEnum.getKey())) {
            return new HeadersExchange(exchangeName, durable, autoDelete, null);
        }
        return new DirectExchange(exchangeName, durable, autoDelete, null);
    }


    /**
     * Is durable boolean.
     *
     * @return the boolean
     */
    public boolean isDurable() {
        return durable;
    }

    /**
     * Sets durable.
     *
     * @param durable the durable
     */
    public void setDurable(boolean durable) {
        this.durable = durable;
    }

    /**
     * Is auto delete boolean.
     *
     * @return the boolean
     */
    public boolean isAutoDelete() {
        return autoDelete;
    }

    /**
     * Sets auto delete.
     *
     * @param autoDelete the auto delete
     */
    public void setAutoDelete(boolean autoDelete) {
        this.autoDelete = autoDelete;
    }

    /**
     * Gets rabbit template.
     *
     * @return the rabbit template
     */
    public RabbitTemplate getRabbitTemplate() {
        return rabbitTemplate;
    }

    /**
     * Sets rabbit template.
     *
     * @param rabbitTemplate the rabbit template
     */
    public void setRabbitTemplate(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    /**
     * Gets queue name.
     *
     * @return the queue name
     */
    public String getQueueName() {
        return queueName;
    }

    /**
     * Sets queue name.
     *
     * @param queueName the queue name
     */
    public void setQueueName(String queueName) {
        this.queueName = queueName;
    }

    /**
     * Gets routing key.
     *
     * @return the routing key
     */
    public String getRoutingKey() {
        return routingKey;
    }

    /**
     * Sets routing key.
     *
     * @param routingKey the routing key
     */
    public void setRoutingKey(String routingKey) {
        this.routingKey = routingKey;
    }

    /**
     * Gets exchangeName.
     *
     * @return the exchangeName
     */
    public String getExchangeName() {
        return exchangeName;
    }

    /**
     * Sets exchangeName.
     *
     * @param exchangeName the exchangeName
     */
    public void setExchangeName(String exchangeName) {
        this.exchangeName = exchangeName;
    }

    /**
     * Gets exchangeName type enum.
     *
     * @return the exchangeName type enum
     */
    public ExchangeTypeEnum getExchangeTypeEnum() {
        return exchangeTypeEnum;
    }

    /**
     * Sets exchangeName type enum.
     *
     * @param exchangeTypeEnum the exchangeName type enum
     */
    public void setExchangeTypeEnum(ExchangeTypeEnum exchangeTypeEnum) {
        this.exchangeTypeEnum = exchangeTypeEnum;
    }
}
